﻿#region Copyright Information
/* +------------------------------------------------+
 * |                    GateShift                   |
 * |================================================|
 * | GateShift is open source software under terms  |
 * | of the GPL License Agreement. All code rights  |
 * | are reserved by the project owner and can be   |
 * | changed or revoked at any time. All artistic   |
 * | works of art (i.e 3D Models, Worlds, ...) used |
 * | in this project fall under the artist terms of |
 * | agreement.                                     |
 * |================================================|
 * |    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT   |
 * |    WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   |
 * | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
 * |    MERCHANTABILITY, FITNESS FOR A PARTICULAR   |
 * | PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
 * | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR |
 * | ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER |
 * |  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,  |
 * | ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
 * |  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE  |
 * |                    SOFTWARE.                   |
 * +------------------------------------------------+
 * | Copyright © 2008-2009 By FastNET Services.     |
 * | All Rights Reserved.                           |
 * +------------------------------------------------+  
 */
#endregion
#region Usings

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using Microsoft.Practices.EnterpriseLibrary.Logging;

#endregion

namespace GateShift.Servers.GameServer.LoggingSystem
{
    public static class Log
    {
        public static event EventHandler<LogEventArgs> EventLogged;

        public static void OnEventLogged(LogMessage message)
        {
            if (EventLogged != null)
                EventLogged(null, new LogEventArgs(message));
        }

        public static void AddEntry(LogMessage logMessage)
        {
            LogEntry entry = new LogEntry
                                 {
                                     Win32ThreadId = logMessage.ThreadID,
                                     Title = logMessage.Title,
                                     TimeStamp = logMessage.TimeStamp.ToUniversalTime(),
                                     Severity = logMessage.Severity,
                                     ProcessName = logMessage.ProcessName,
                                     ProcessId = logMessage.ProcessID,
                                     Priority = logMessage.Priority,
                                     Message = logMessage.Description,
                                     ManagedThreadName = logMessage.ManagedThreadName,
                                     MachineName = Environment.MachineName,
                                     EventId = logMessage.EventID,
                                     AppDomainName = logMessage.AppDomainName,
                                     ActivityId = logMessage.ActivityID
                                 };

            foreach (int category in logMessage.Categories)
                entry.Categories.Add(category.ToString());

            if (!Logger.ShouldLog(entry) || !Logger.IsLoggingEnabled()) return;

            OnEventLogged(logMessage);
            Logger.Write(entry);
        }

        #region Multiple Category

        public static void AddMultiCategoryEntry(string title, string description, string managedThreadName, string threadID, string appDomainName,
                                                 Guid activityID, LogPriorities priority, int eventID, TraceEventType severity, IEnumerable<int> categories)
        {
            LogMessage logMessage = new LogMessage
                                        {
                                            Title = title,
                                            TimeStamp = DateTime.UtcNow,
                                            ThreadID = threadID,
                                            Severity = severity,
                                            ProcessName = Process.GetCurrentProcess().ProcessName,
                                            ProcessID = Process.GetCurrentProcess().Id.ToString(),
                                            Priority = (int)priority,
                                            ManagedThreadName = managedThreadName,
                                            EventID = eventID,
                                            Description = description,
                                            AppDomainName = appDomainName,
                                            ActivityID = activityID
                                        };

            logMessage.Categories.AddRange(categories);

            AddEntry(logMessage);
        }

        public static void AddMultiCategoryEntry(string title, string description, string managedThreadName, string threadID, string appDomainName,
                                                 LogPriorities priority, int eventID, TraceEventType severity, IEnumerable<int> categories)
        {
            AddMultiCategoryEntry(title, description, managedThreadName, threadID, appDomainName, Guid.NewGuid(), priority, eventID, severity, categories);
        }

        public static void AddMultiCategoryEntry(string title, string description, string managedThreadName, string threadID, string appDomainName,
                                                 LogPriorities priority, TraceEventType severity, IEnumerable<int> categories)
        {
            AddMultiCategoryEntry(title, description, managedThreadName, threadID, appDomainName, priority, -1, severity, categories);
        }

        public static void AddMultiCategoryEntry(string title, string description, string managedThreadName, string threadID, string appDomainName,
                                                 TraceEventType severity, IEnumerable<int> categories)
        {
            AddMultiCategoryEntry(title, description, managedThreadName, threadID, appDomainName, LogPriorities.Undefined, severity, categories);
        }

        public static void AddMultiCategoryEntry(string title, string description, string appDomainName, LogPriorities priority, int eventID,
                                                 TraceEventType severity, IEnumerable<int> categories)
        {
            string managedThreadName = Thread.CurrentThread.Name;
            string threadID = Thread.CurrentThread.ManagedThreadId.ToString();

            AddMultiCategoryEntry(title, description, managedThreadName, threadID, appDomainName, Guid.NewGuid(), priority, eventID, severity, categories);
        }

        public static void AddMultiCategoryEntry(string title, string description, string appDomainName, LogPriorities priority, TraceEventType severity,
                                                 IEnumerable<int> categories)
        {
            AddMultiCategoryEntry(title, description, appDomainName, priority, -1, severity, categories);
        }

        public static void AddMultiCategoryEntry(string title, string description, string appDomainName, TraceEventType severity, IEnumerable<int> categories)
        {
            AddMultiCategoryEntry(title, description, appDomainName, LogPriorities.Undefined, severity, categories);
        }

        public static void AddMultiCategoryEntry(string title, string description,
                                                 LogPriorities priority, int eventID, TraceEventType severity, IEnumerable<int> categories)
        {
            string appDomainName = AppDomain.CurrentDomain.FriendlyName;

            AddMultiCategoryEntry(title, description, appDomainName, priority, eventID, severity, categories);
        }

        public static void AddMultiCategoryEntry(string title, string description, LogPriorities priority, TraceEventType severity, IEnumerable<int> categories)
        {
            AddMultiCategoryEntry(title, description, priority, -1, severity, categories);
        }

        public static void AddMultiCategoryEntry(string title, string description, TraceEventType severity, IEnumerable<int> categories)
        {
            AddMultiCategoryEntry(title, description, LogPriorities.Undefined, severity, categories);
        }

        public static void AddMultiCategoryEntry(string title, string description, IEnumerable<int> categories)
        {
            AddMultiCategoryEntry(title, description, TraceEventType.Verbose, categories);
        }

        #endregion

        #region Single Category

        public static void AddEntry(string title, string description, string managedThreadName, string threadID, string appDomainName, Guid activityID,
                                    LogPriorities priority, int eventID, TraceEventType severity, int category)
        {
            AddMultiCategoryEntry(title, description, managedThreadName, threadID, appDomainName, activityID, priority, eventID, severity,
                                  new List<int> { category });
        }

        public static void AddEntry(string title, string description, string managedThreadName, string threadID,
                                    string appDomainName, LogPriorities priority, int eventID, TraceEventType severity, int category)
        {
            AddEntry(title, description, managedThreadName, threadID, appDomainName, Guid.NewGuid(), priority, eventID, severity, category);
        }

        public static void AddEntry(string title, string description, string managedThreadName, string threadID, string appDomainName,
                                    LogPriorities priority, TraceEventType severity, int category)
        {
            AddEntry(title, description, managedThreadName, threadID, appDomainName, priority, 0, severity, category);
        }

        public static void AddEntry(string title, string description, string managedThreadName, string threadID, string appDomainName,
                                    TraceEventType severity, int category)
        {
            AddEntry(title, description, managedThreadName, threadID, appDomainName, 0, severity, category);
        }

        public static void AddEntry(string title, string description, string appDomainName, LogPriorities priority, int eventID,
                                    TraceEventType severity, int category)
        {
            string managedThreadName = Thread.CurrentThread.Name;
            string threadID = Thread.CurrentThread.ManagedThreadId.ToString();

            AddEntry(title, description, managedThreadName, threadID, appDomainName, priority, eventID, severity, category);
        }

        public static void AddEntry(string title, string description, string appDomainName, LogPriorities priority, TraceEventType severity, int category)
        {
            AddEntry(title, description, appDomainName, priority, 0, severity, category);
        }

        public static void AddEntry(string title, string description, string appDomainName, TraceEventType severity, int category)
        {
            AddEntry(title, description, appDomainName, 0, severity, category);
        }

        public static void AddEntry(string title, string description, LogPriorities priority, int eventID, TraceEventType severity, int category)
        {
            string appDomainName = AppDomain.CurrentDomain.FriendlyName;

            AddEntry(title, description, appDomainName, priority, eventID, severity, category);
        }

        public static void AddEntry(string title, string description, LogPriorities priority, TraceEventType severity, int category)
        {
            AddEntry(title, description, priority, 0, severity, category);
        }

        public static void AddEntry(string title, string description, TraceEventType severity, int category)
        {
            AddEntry(title, description, 0, severity, category);
        }

        public static void AddEntry(string title, string description, int category)
        {
            AddEntry(title, description, 0, TraceEventType.Verbose, category);
        }

        #endregion

        #region No Category

        public static void AddUncategorizedEntry(string title, string description, string managedThreadName, string threadID, string appDomainName, Guid activityID, LogPriorities priority, int eventID, TraceEventType severity)
        {
            AddMultiCategoryEntry(title, description, managedThreadName, threadID, appDomainName, activityID, priority, eventID, severity, new List<int>());
        }

        public static void AddUncategorizedEntry(string title, string description, string managedThreadName, string threadID, string appDomainName, LogPriorities priority, int eventID, TraceEventType severity)
        {
            AddUncategorizedEntry(title, description, managedThreadName, threadID, appDomainName, Guid.NewGuid(), priority, eventID, severity);
        }

        public static void AddUncategorizedEntry(string title, string description, string managedThreadName, string threadID, string appDomainName, LogPriorities priority, TraceEventType severity)
        {
            AddUncategorizedEntry(title, description, managedThreadName, threadID, appDomainName, priority, -1, severity);
        }

        public static void AddUncategorizedEntry(string title, string description, string managedThreadName, string threadID, string appDomainName, TraceEventType severity)
        {
            AddUncategorizedEntry(title, description, managedThreadName, threadID, appDomainName, LogPriorities.Undefined, severity);
        }

        public static void AddUncategorizedEntry(string title, string description, string appDomainName, LogPriorities priority, int eventID, TraceEventType severity)
        {
            string managedThreadName = Thread.CurrentThread.Name;
            string threadID = Thread.CurrentThread.ManagedThreadId.ToString();

            AddUncategorizedEntry(title, description, managedThreadName, threadID, appDomainName, priority, eventID, severity);
        }

        public static void AddUncategorizedEntry(string title, string description, string appDomainName, LogPriorities priority, TraceEventType severity)
        {
            AddUncategorizedEntry(title, description, appDomainName, priority, 0, severity);
        }

        public static void AddUncategorizedEntry(string title, string description, string appDomainName, TraceEventType severity)
        {
            AddUncategorizedEntry(title, description, appDomainName, 0, severity);
        }

        public static void AddUncategorizedEntry(string title, string description, LogPriorities priority, int eventID, TraceEventType severity)
        {
            string appDomainName = AppDomain.CurrentDomain.FriendlyName;

            AddUncategorizedEntry(title, description, appDomainName, priority, eventID, severity);
        }

        public static void AddUncategorizedEntry(string title, string description, LogPriorities priority, TraceEventType severity)
        {
            AddUncategorizedEntry(title, description, priority, 0, severity);
        }

        public static void AddUncategorizedEntry(string title, string description, TraceEventType severity)
        {
            AddUncategorizedEntry(title, description, 0, severity);
        }

        public static void AddUncategorizedEntry(string title, string description)
        {
            AddUncategorizedEntry(title, description, TraceEventType.Verbose);
        }

        #endregion
    }
}